import Fastify, { FastifyInstance } from 'fastify';
import cors from '@fastify/cors';
import helmet from '@fastify/helmet';
import rateLimit from '@fastify/rate-limit';
import { disconnectDatabase } from '../mongodb/index.js';
import { ConfigLoader, type MCPConfig } from '../core/config/index.js';
import { errorHandler, loggingMiddleware } from './middleware/index.js';
import { healthRoutes, messageRoutes } from './routes/index.js';

/**
 * 创建并配置Fastify应用程序
 */
export async function createApp(config?: MCPConfig): Promise<FastifyInstance> {
  const appConfig = config || ConfigLoader.load();

  // 创建Fastify实例
  const fastify = Fastify({
    logger: {
      level: appConfig.server.logLevel,
      transport: process.env['NODE_ENV'] === 'development' ? {
        target: 'pino-pretty',
        options: {
          colorize: true,
          translateTime: 'HH:MM:ss Z',
          ignore: 'pid,hostname'
        }
      } : undefined,
      serializers: {
        req: (req) => ({
          method: req.method,
          url: req.url,
          headers: req.headers,
          hostname: req.hostname,
          remoteAddress: req.ip,
          remotePort: req.socket?.remotePort
        }),
        res: (res) => ({
          statusCode: res.statusCode,
          headers: res.headers
        })
      }
    },
    // 信任代理（用于获取真实客户端IP）
    trustProxy: true,
    // 请求ID生成
    genReqId: () => {
      return `req_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
    },
    // 请求体大小限制
    bodyLimit: 1024 * 1024 * 10, // 10MB
    // 保持连接超时
    keepAliveTimeout: 30000,
    // 连接超时
    connectionTimeout: 30000
  });

  // 注册错误处理中间件
  await fastify.register(errorHandler);

  // 注册日志中间件
  await fastify.register(loggingMiddleware);

  // 注册CORS
  await fastify.register(cors, {
    origin: appConfig.security.corsOrigin === '*' ? true : appConfig.security.corsOrigin,
    methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
    allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With', 'X-Request-ID'],
    credentials: true
  });

  // 注册Helmet安全头 (开发环境宽松配置)
  await fastify.register(helmet, {
    hsts: false,
    // 在开发环境中完全禁用CSP，以方便调试
    contentSecurityPolicy: false,
    crossOriginEmbedderPolicy: false,
    crossOriginOpenerPolicy: false,
    originAgentCluster: false
  });

  // 注册限流
  await fastify.register(rateLimit, {
    max: appConfig.security.rateLimitMax,
    timeWindow: appConfig.security.rateLimitWindow,
    errorResponseBuilder: (request, context) => {
      return {
        success: false,
        error: {
          code: 'RATE_LIMIT_EXCEEDED',
          message: `请求频率过高，请在 ${Math.round(context.ttl / 1000)} 秒后重试`,
          details: {
            limit: context.max,

            resetTime: new Date(Date.now() + context.ttl)
          }
        },
        meta: {
          timestamp: new Date().toISOString(),
          requestId: request.id
        }
      };
    }
  });



  // 注册API路由
  await fastify.register(async function apiRoutes(fastify) {
    // 添加API版本前缀
    await fastify.register(healthRoutes, { prefix: '/api/v1' });
    await fastify.register(messageRoutes, { prefix: '/api/v1' });
  });

  // 添加应用程序关闭钩子
  fastify.addHook('onClose', async (instance) => {
    instance.log.info('应用程序正在关闭...');
    await disconnectDatabase();
  });

  // 添加优雅关闭处理
  const gracefulShutdown = async (signal: string) => {
    fastify.log.info(`收到${signal}信号，开始优雅关闭...`);
    try {
      await fastify.close();
      process.exit(0);
    } catch (error) {
      fastify.log.error('关闭过程中出错: ' + (error as Error).message);
      process.exit(1);
    }
  };

  process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
  process.on('SIGINT', () => gracefulShutdown('SIGINT'));

  return fastify;
}

/**
 * 启动Fastify服务器
 */
export async function startServer(config?: MCPConfig): Promise<FastifyInstance> {
  const appConfig = config || ConfigLoader.load();
  const app = await createApp(appConfig);

  try {
    await app.listen({
      port: appConfig.server.port,
      host: appConfig.server.host
    });

    app.log.info({
      port: appConfig.server.port,
      host: appConfig.server.host,
      env: process.env['NODE_ENV'] || 'development',
      version: process.env['npm_package_version'] || '1.0.0'
    }, `🚀 MCP API 服务器已启动`);


    app.log.info(`❤️  健康检查: http://${appConfig.server.host}:${appConfig.server.port}/api/v1/health`);

    return app;
  } catch (error) {
    app.log.error('启动服务器失败:' + (error as Error).message);
    process.exit(1);
  }
}
